home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / System / SmartDragWindow 1.0.1 / SmartDragWindow INIT / Sourcery / SmartDragWindow INIT.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-22  |  4.8 KB  |  177 lines  |  [TEXT/CWIE]

  1. /*
  2.     11/17/95
  3.  
  4.     Source code taken very "liberally" from Jorg Brown's sample
  5.     INIT code from Ultimate Mac Programming. Without it, writing
  6.     the SmartDragWindow extension would have been much more work.
  7. */
  8.  
  9.  
  10. #include <OSUtils.h>
  11. #include "SmartDragWindow INIT.h"
  12. #include "SmartDragWindow.h"
  13.  
  14. enum {
  15.     uppDragWindowProcInfo = kPascalStackBased
  16.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))
  17.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Point)))
  18.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Rect*)))
  19. };
  20.  
  21. // ---------------------------------------------------------------------------
  22.  
  23. // Globals
  24.  
  25. SmartDragGlobals gSmartDragData = {
  26.     true,        // smartDrag on/off
  27.     10,            // snap-to-distance
  28.     true,        // snap to monitor
  29.     true,        // snap to window
  30.     false,        // snap to grid
  31.     10,            // snap grid size
  32.     false,        // snap when growing window
  33.     
  34.     0            // reserved
  35. };
  36.  
  37. // Address of old DragWindow() trap
  38. pascal void (*gOldDragWindow)(WindowPtr theWindow, Point startPt, Rect *limitRect);
  39. // Address of gestalt selector function
  40. SelectorFunctionUPP gSmartDragGestaltUPP;
  41.  
  42. // ---------------------------------------------------------------------------
  43.  
  44. pascal void SmarterDragWindow(WindowPtr w, Point pt, Rect *bounds);
  45. static pascal OSErr SmartDragGestalt(OSType selector, long *_response);
  46.  
  47. // ---------------------------------------------------------------------------
  48.  
  49. void main(void) {
  50.     long oldA4;
  51.     THz oldZone;
  52.     SmartDragGlobals **dragGlobals;
  53.     UniversalProcPtr newDragWindow;
  54.     
  55.     // Setup A4 to access globals
  56.     oldA4 = SetCurrentA4();
  57.  
  58.     // Set current zone to system heap zone.
  59.     oldZone = GetZone();
  60.     SetZone(SystemZone());
  61.  
  62.     // Since we rely on Gestalt we have to make sure it's available
  63.     if (GetOSTrapAddress(kGestaltTrapNumber) == UnimplementedTrapAddress) {
  64.         goto exitSection;
  65.     }
  66.  
  67.     // Get gestalt selector function
  68.     gSmartDragGestaltUPP = NewSelectorFunctionProc(SmartDragGestalt);
  69.     if (gSmartDragGestaltUPP == NULL) {
  70.         goto exitSection;
  71.     }
  72.     
  73.     // Install selector to allow us to communicate with the control
  74.     // panel & to make sure we don't load twice.
  75.     if (NewGestalt(kSmartDragSignature, gSmartDragGestaltUPP) != noErr) {
  76.         goto exitSection;
  77.     }
  78.     
  79.     newDragWindow = NewRoutineDescriptor((ProcPtr)
  80.         &SmarterDragWindow, uppDragWindowProcInfo, GetCurrentISA());
  81.     if (newDragWindow == NULL) {
  82.         goto exitSection;
  83.     }
  84.  
  85.     DetachResource(GetResource('INIT', kSmartDragRsrcID));
  86.     
  87.     // Remember old implementation of DragWindow
  88.     gOldDragWindow = (void*)GetToolTrapAddress(kDragWindowTrapNumber);
  89.  
  90.     // Patch ourselves in
  91.     SetToolTrapAddress(newDragWindow, kDragWindowTrapNumber);
  92.     
  93.     // Load in preferences
  94.     dragGlobals = (SmartDragGlobals**)Get1Resource(kSmartDragPrefRsrcType,
  95.         kSmartDragRsrcID);
  96.     if (dragGlobals != NULL && GetHandleSize((Handle)dragGlobals) ==
  97.         sizeof(SmartDragGlobals)) {
  98.         gSmartDragData = **dragGlobals;
  99.     }
  100.     
  101. exitSection:
  102.     SetZone(oldZone);
  103.     SetA4(oldA4);
  104. } // END main entrypoint
  105.  
  106. // ---------------------------------------------------------------------------
  107.  
  108. static void SnapProc(WindowPtr windowToDrag, short snapToDistance, Rect *snapRect);
  109.  
  110. pascal void SmarterDragWindow(WindowPtr w, Point pt, Rect *bounds) {
  111.     long oldA4;
  112.     
  113.     oldA4 = SetCurrentA4();
  114.  
  115.     // Hot key: control key to turn off smart dragging
  116.     if (IsControlKeyDown() || !gSmartDragData.smartDragOn) {
  117.         // Call original DragWindow() trap
  118. #ifdef powerc
  119.         CallUniversalProc((UniversalProcPtr)gOldDragWindow,
  120.             uppDragWindowProcInfo, w, pt, bounds);
  121. #else
  122.         gOldDragWindow(w, pt, bounds);
  123. #endif
  124.     }
  125.     else {
  126.         // Call our own routine
  127.         SuperSmartDragWindow(w, pt, bounds,
  128.             gSmartDragData.snapToDistance, SnapProc);
  129.     }
  130.     
  131.     SetA4(oldA4);
  132. } // END SmarterDragWindow
  133.  
  134. void SnapProc(WindowPtr windowToDrag, short snapToDistance, Rect *snapRect) {
  135.     if (gSmartDragData.snapToGrid)
  136.         GridSnapProc(windowToDrag, gSmartDragData.snapGridSize, snapRect);
  137.     if (gSmartDragData.snapToWindows)
  138.         WindowSnapProc(windowToDrag, snapToDistance, snapRect);
  139.     if (gSmartDragData.snapToMonitor)
  140.         MonitorSnapProc(windowToDrag, snapToDistance, snapRect);
  141. } // END SnapProc
  142.  
  143. // ---------------------------------------------------------------------------
  144.  
  145. pascal OSErr SmartDragGestalt(OSType selector, long *_response) {
  146.     long oldA4;
  147.     OSErr err = noErr;
  148.     
  149.     // Setup A4 to access globals
  150.     oldA4 = SetCurrentA4();
  151.     
  152.     switch(selector) {
  153.         case kGestaltGetSmartDragGlobals:
  154.             // Caller (control panel) wants access to our globals
  155.             *_response = (long)&gSmartDragData;
  156.         break;
  157.         
  158.         case kSmartDragSignature:
  159.             // Caller wants address of gestalt selector
  160.             *_response = (long)gSmartDragGestaltUPP;
  161.         break;
  162.         
  163.         case gestaltVersion:
  164.             // Caller (control panel) wants the INIT version
  165.             // to make sure it matches that of the control panel
  166.             *_response = kSmartDragVersion;
  167.         break;
  168.         
  169.         default:
  170.             // We don't handle any other gestalt selectors
  171.             err = gestaltUnknownErr;
  172.         break;
  173.     }
  174.     
  175.     SetA4(oldA4);
  176.     return(err);
  177. } // END SmartDragGestalt